package quartz.service;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ControllerAdvice;
import quartz.util.SpringUtil;

import java.beans.Introspector;
import java.lang.reflect.ParameterizedType;
import java.util.List;

@Service
@ControllerAdvice
public abstract class BaseService<T, ID> {
  @SuppressWarnings("unchecked")
  protected Class<T> getTClass() {
    return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
  }

  protected String getCollectionName() {
    return Introspector.decapitalize(this.getTClass().getSimpleName());
  }

  protected String getRepositoryBeanName() {
    return String.format("%sRepository", this.getCollectionName());
  }

  @SuppressWarnings("unchecked")
  protected PagingAndSortingRepository<T, ID> getRepository() {
    return (PagingAndSortingRepository<T, ID>) SpringUtil.getBean(this.getRepositoryBeanName());
  }

  public T findById(ID id) {
    return getRepository().findById(id).orElse(null);
  }

  public T save(T t) {
    return getRepository().save(t);
  }

  public Iterable<T> saveAll(Iterable<T> ts) {
    return getRepository().saveAll(ts);
  }

  public void deleteById(ID id) {
    getRepository().deleteById(id);
  }

  public void deleteAll(List<ID> ids) {
    ids.forEach(id -> getRepository().deleteById(id));
  }

  public Iterable<T> findAll() {
    return getRepository().findAll();
  }

  public Iterable<T> findAll(Sort sort) {
    return getRepository().findAll(sort);
  }

  public Page<T> findAll(Pageable pageable) {
    return getRepository().findAll(pageable);
  }
}